package handlers

import (
	"strconv"
	"sysu-giep/internal/api/middleware"
	"sysu-giep/internal/database/models"
	"sysu-giep/internal/service"
	"sysu-giep/pkg/logger"
	"sysu-giep/pkg/response"

	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

var adminService *service.AdminService

// InitAdminHandlers 初始化管理员处理器
func InitAdminHandlers(as *service.AdminService) {
	adminService = as
}

// AdminGetUsers 管理员获取用户列表
// @Summary 管理员获取用户列表
// @Description 管理员获取用户列表，支持分页和筛选
// @Tags 管理员
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param page query int false "页码" default(1)
// @Param size query int false "每页大小" default(10)
// @Param role query string false "角色"
// @Param status query string false "状态"
// @Success 200 {object} response.PageResponse{data=[]models.User}
// @Router /admin/users [get]
func AdminGetUsers(c *gin.Context) {
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	size, _ := strconv.Atoi(c.DefaultQuery("size", "10"))
	role := c.Query("role")
	status := c.Query("status")

	// 参数验证
	if page < 1 {
		page = 1
	}
	if size < 1 || size > 100 {
		size = 10
	}

	logger.Info("管理员获取用户列表",
		logger.Int("page", page),
		logger.Int("size", size),
		logger.String("role", role),
		logger.String("status", status),
	)

	users, total, err := adminService.GetUsers(page, size, role, status)
	if err != nil {
		logger.ErrorLog("获取用户列表失败", zap.Error(err))
		response.InternalServerError(c, "获取用户列表失败: "+err.Error())
		return
	}

	response.PageSuccess(c, users, total, page, size)
}

// AdminUpdateUserStatus 管理员更新用户状态
// @Summary 管理员更新用户状态
// @Description 管理员更新用户审核状态
// @Tags 管理员
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param id path int true "用户ID"
// @Param request body UpdateUserStatusRequest true "状态信息"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.Response
// @Router /admin/users/{id}/status [put]
func AdminUpdateUserStatus(c *gin.Context) {
	adminID := middleware.GetCurrentUserID(c)
	idStr := c.Param("id")

	var req models.UpdateUserStatusRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.BadRequest(c, "请求参数错误: "+err.Error())
		return
	}

	userID, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		response.BadRequest(c, "无效的用户ID")
		return
	}

	logger.Info("管理员更新用户状态",
		logger.Int64("admin_id", int64(adminID)),
		logger.Int64("user_id", int64(userID)),
		logger.String("status", string(req.Status)),
	)

	if err := adminService.UpdateUserStatus(uint(userID), req.Status); err != nil {
		logger.ErrorLog("更新用户状态失败", zap.Error(err))
		response.InternalServerError(c, "更新用户状态失败: "+err.Error())
		return
	}

	response.SuccessWithMessage(c, "用户状态更新成功", nil)
}

// AdminGetProjects 管理员获取课题列表
// @Summary 管理员获取课题列表
// @Description 管理员获取课题列表，支持分页和筛选
// @Tags 管理员
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param page query int false "页码" default(1)
// @Param size query int false "每页大小" default(10)
// @Param status query string false "状态"
// @Success 200 {object} response.PageResponse{data=[]models.Project}
// @Router /admin/projects [get]
func AdminGetProjects(c *gin.Context) {
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	size, _ := strconv.Atoi(c.DefaultQuery("size", "10"))
	status := c.Query("status")

	// 参数验证
	if page < 1 {
		page = 1
	}
	if size < 1 || size > 100 {
		size = 10
	}

	logger.Info("管理员获取课题列表",
		logger.Int("page", page),
		logger.Int("size", size),
		logger.String("status", status),
	)

	projects, total, err := adminService.GetProjects(page, size, status)
	if err != nil {
		logger.ErrorLog("获取课题列表失败", zap.Error(err))
		response.InternalServerError(c, "获取课题列表失败: "+err.Error())
		return
	}

	response.PageSuccess(c, projects, total, page, size)
}

// AdminUpdateProjectStatus 管理员更新课题状态
// @Summary 管理员更新课题状态
// @Description 管理员更新课题状态
// @Tags 管理员
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param id path int true "课题ID"
// @Param request body UpdateProjectStatusRequest true "状态信息"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.Response
// @Router /admin/projects/{id}/status [put]
func AdminUpdateProjectStatus(c *gin.Context) {
	adminID := middleware.GetCurrentUserID(c)
	idStr := c.Param("id")

	var req models.UpdateProjectStatusRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.BadRequest(c, "请求参数错误: "+err.Error())
		return
	}

	projectID, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		response.BadRequest(c, "无效的课题ID")
		return
	}

	logger.Info("管理员更新课题状态",
		logger.Int64("admin_id", int64(adminID)),
		logger.Int64("project_id", int64(projectID)),
		logger.String("status", string(req.Status)),
	)

	if err := adminService.UpdateProjectStatus(uint(projectID), req.Status); err != nil {
		logger.ErrorLog("更新课题状态失败", zap.Error(err))
		response.InternalServerError(c, "更新课题状态失败: "+err.Error())
		return
	}

	response.SuccessWithMessage(c, "课题状态更新成功", nil)
}

// AdminGetApplications 管理员获取申请列表
// @Summary 管理员获取申请列表
// @Description 管理员获取申请列表，支持分页和筛选
// @Tags 管理员
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param page query int false "页码" default(1)
// @Param size query int false "每页大小" default(10)
// @Param status query string false "状态"
// @Success 200 {object} response.PageResponse{data=[]models.Application}
// @Router /admin/applications [get]
func AdminGetApplications(c *gin.Context) {
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	size, _ := strconv.Atoi(c.DefaultQuery("size", "10"))
	status := c.Query("status")

	// 参数验证
	if page < 1 {
		page = 1
	}
	if size < 1 || size > 100 {
		size = 10
	}

	logger.Info("管理员获取申请列表",
		logger.Int("page", page),
		logger.Int("size", size),
		logger.String("status", status),
	)

	applications, total, err := adminService.GetApplications(page, size, status)
	if err != nil {
		logger.ErrorLog("获取申请列表失败", zap.Error(err))
		response.InternalServerError(c, "获取申请列表失败: "+err.Error())
		return
	}

	response.PageSuccess(c, applications, total, page, size)
}

// AdminUpdateApplicationStatus 管理员更新申请状态
// @Summary 管理员更新申请状态
// @Description 管理员更新申请状态
// @Tags 管理员
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param id path int true "申请ID"
// @Param request body UpdateApplicationStatusRequest true "状态信息"
// @Success 200 {object} response.Response
// @Failure 400 {object} response.Response
// @Router /admin/applications/{id}/status [put]
func AdminUpdateApplicationStatus(c *gin.Context) {
	adminID := middleware.GetCurrentUserID(c)
	idStr := c.Param("id")

	var req models.AdminUpdateApplicationStatusRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		response.BadRequest(c, "请求参数错误: "+err.Error())
		return
	}

	applicationID, err := strconv.ParseUint(idStr, 10, 32)
	if err != nil {
		response.BadRequest(c, "无效的申请ID")
		return
	}

	logger.Info("管理员更新申请状态",
		logger.Int64("admin_id", int64(adminID)),
		logger.Int64("application_id", int64(applicationID)),
		logger.String("status", string(req.Status)),
	)

	if err := adminService.UpdateApplicationStatus(uint(applicationID), req.Status, req.Feedback); err != nil {
		logger.ErrorLog("更新申请状态失败", zap.Error(err))
		response.InternalServerError(c, "更新申请状态失败: "+err.Error())
		return
	}

	response.SuccessWithMessage(c, "申请状态更新成功", nil)
}

// AdminGetStatistics 管理员获取统计信息
// @Summary 管理员获取统计信息
// @Description 管理员获取平台统计信息
// @Tags 管理员
// @Accept json
// @Produce json
// @Security BearerAuth
// @Success 200 {object} response.Response{data=map[string]interface{}}
// @Router /admin/statistics [get]
func AdminGetStatistics(c *gin.Context) {
	logger.Info("管理员获取统计信息")

	statistics, err := adminService.GetStatistics()
	if err != nil {
		logger.ErrorLog("获取统计信息失败", zap.Error(err))
		response.InternalServerError(c, "获取统计信息失败: "+err.Error())
		return
	}

	response.Success(c, statistics)
}

// AdminExportStatistics 管理员导出统计报表
// @Summary 管理员导出统计报表
// @Description 管理员导出统计报表
// @Tags 管理员
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param format query string false "导出格式" default(excel)
// @Success 200 {object} response.Response
// @Router /admin/statistics/export [get]
func AdminExportStatistics(c *gin.Context) {
	format := c.DefaultQuery("format", "excel")

	logger.Info("管理员导出统计报表", logger.String("format", format))

	// TODO: 实现导出功能
	response.Success(c, gin.H{
		"message":      "导出功能开发中",
		"format":       format,
		"download_url": "/downloads/statistics.xlsx",
		"filename":     "statistics.xlsx",
	})
}
